import './SetAdminRouter.scss'

import { Http } from '../../Utils/Api'
import { FormTempMapping } from '../../Utils/FormTemp'
import { fieldDefaultData } from '../../Config/default'
import { FlowMenuMapping, FlowThemeFormMapping } from '../../Config/FlowConfig'

import { v4 } from 'uuid'
import { App, Button, Spin, Tree, Tooltip, Popconfirm } from 'antd'
import { useState } from 'react'
import { useRequest } from 'alova/client'
import { useEventEmitter, useMount } from 'ahooks'

import { MenuFiledTemp } from '../../Utils/DndKit'
import { modelStore } from '../../Config/zustand'
import { MappingData } from '../../Config/MappingData'
import { removeTreeByKey, treeValue, replaceNodeById, getDifferentObjectsOptimized } from '../../Utils'
import { ICONMapping } from '../../Config/IconMapping'


const setFieldStatus = (fieldArr, data) => {
    const dataSet = new Set(data);
    return fieldArr.map(item => ({ ...item, status: dataSet.has(item.dataField) ? 1 : 0 }))
}

const addNewFields = (oldData, data) => {
    const existingCaptions = new Set(oldData.map(item => item.dataField))
    const newCaptions = data.filter(item => !existingCaptions.has(item))
    const newFieldObjects = newCaptions.map(dataField => ({ ...fieldDefaultData, id: v4(), dataField: dataField, caption: dataField, status: 2 }))
    return [...oldData, ...newFieldObjects]
}

const SetAdminRouter = ({ data, Off }) => {
    const { updateModel } = modelStore()
    const { notification } = App.useApp()
    const { flowUrl, init, DevEvent, field } = data
    const { uuid, type, subset } = FlowMenuMapping[flowUrl]

    const { send } = useRequest(data => Http(data), { immediate: false })

    const RouterEvent = useEventEmitter()
    RouterEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'onFormBack') {
            DevEvent.emit({ type: 'onModifyJsonData', data: { type: uuid, url: flowUrl, data } })
        }
    })
    DevEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'closeFormLoading') RouterEvent.emit({ type: 'closeFormLoading' })
        if (type === 'closeForm') Off()
    })

    if (type === 'form') {
        return (
            <div className='SetAdminRouter'>
                <FormTempMapping formItem={FlowThemeFormMapping[flowUrl]} FORMEVENT={RouterEvent} Initial={init} />
            </div>
        )
    }
    if (type === 'field') {
        // TODO status 0:废弃 1:原有 2:新增
        const [FieldData, setFieldData] = useState()

        const FieldEvent = useEventEmitter()
        FieldEvent.useSubscription(val => {
            const { type, data } = val
            if (type === 'onUpdate') setFieldData(data)
        })

        useMount(async () => {
            const { fieldArr, fieldMenu } = init
            if (!fieldMenu) {
                notification.error({ key: 'devPage', message: '未获取配置!', description: '请先配置 接口设置 中的 菜单字段!', showProgress: true })
                Off()
                return false
            }
            const { data } = await send({ method: 'get', url: 'menu/GetMenuColumnList', params: { MenuType: fieldMenu } })

            if (fieldArr) {
                const oldData = setFieldStatus(fieldArr, data)
                const newData = addNewFields(oldData, data)
                setFieldData(newData)
            } else {
                const arr = data.map(key => ({ ...fieldDefaultData, id: v4(), dataField: key, caption: key, status: 2 }))
                setFieldData(arr)
            }
        })

        const onSave = () => {
            DevEvent.emit({ type: 'onSaveFieldData', data: FieldData })
            Off()
        }

        if (FieldData) {
            return (
                <div className='SetAdminRouter'>
                    <MenuFiledTemp data={FieldData} FieldEvent={FieldEvent} />
                    <div className='SaveBtn'>
                        <Button type='primary' size='large' onClick={onSave}>保存字段</Button>
                    </div>
                </div>
            )
        } else {
            return (
                <div className='SetAdminRouter'>
                    <Spin />
                </div>
            )
        }
    }

    if (type === 'option') {
        const TypeMapping = {
            top: { type: MappingData.System__TopOptionsType },
            row: { type: MappingData.System__RowOptionsType }
        }
        const [TreeData, setTreeData] = useState(init || [])

        const [FieldUuid, setFieldUuid] = useState()


        const FORMEVENT = useEventEmitter()
        FORMEVENT.useSubscription(val => {
            const { type, data } = val
            if (type === 'onFormBack') {
                const arr = [...TreeData, { uuid: v4(), ...data }]
                setTreeData(arr)
                FORMEVENT.emit({ type: 'onClearBox' })
            }
            if (type === 'onSaveField') {
                const old = JSON.parse(JSON.stringify(TreeData))
                old.find(v => v.uuid === FieldUuid).field = data
                setTreeData(old)
            }
            if (type === 'onSaveBands') {
                const old = JSON.parse(JSON.stringify(TreeData))
                old.find(v => v.uuid === FieldUuid).bands = data
                setTreeData(old)
            }
        })

        const ModifyEvent = useEventEmitter()
        ModifyEvent.useSubscription(val => {
            const { type, data } = val
            if (type === 'onFormBack') {
                const oldData = treeValue(TreeData, data.uuid)
                const newData = { ...oldData, ...data }
                const newTree = replaceNodeById(TreeData, data.uuid, newData)
                setTreeData(newTree)
                ModifyEvent.emit({ type: 'onClearBox' })
            }
        })

        const onAddOptions = () => {
            updateModel({ type: 'SetAdminOptions', width: 640, title: '新增操作功能', data: { type: 'AddOptions', FORMEVENT, data: subset } })
        }

        const onModify = (e) => {
            updateModel({ type: 'SetAdminOptions', width: 640, title: '修改操作功能', data: { type: 'setOptions', options: e.type, FORMEVENT: ModifyEvent, init: e } })
        }

        const onField = (e) => {
            setFieldUuid(e.uuid)
            // const data = getDifferentObjectsOptimized(e.field, field, 'id')
            // console.log(data)
            const FieldArr = e.field || field
            updateModel({ type: 'SetAdminOptions', width: 720, title: '功能字段设置', data: { type: 'setField', FORMEVENT, init: FieldArr } })
        }

        const onSearch = (e) => {
            setFieldUuid(e.uuid)
            const FieldArr = e.field || []
            updateModel({ type: 'SetAdminOptions', width: 720, title: '搜索字段设置', data: { type: 'setSearch', FORMEVENT, init: FieldArr } })
        }

        const onSort = (e) => {
            setFieldUuid(e.uuid)
            const FieldArr = e.field || []
            updateModel({ type: 'SetAdminOptions', width: 720, title: '排序字段设置', data: { type: 'setSort', FORMEVENT, init: FieldArr } })
        }

        const onBands = e => {
            if (!e.field) {
                notification.warning({ key: 'devPage', message: '操作提醒!', description: '请先配置 字段 !' })
                return false
            } else {
                setFieldUuid(e.uuid)
                updateModel({ type: 'SetAdminOptions', width: 720, title: '设置多层列头', data: { type: 'setBands', FORMEVENT, init: e } })
            }
        }

        const onDelete = (e) => {
            setTreeData(removeTreeByKey(TreeData, e))
        }

        const onSaveButton = () => {
            DevEvent.emit({ type: subset, data: TreeData })
        }

        const onDrop = (info) => {
            const dropKey = info.node.uuid;
            const dragKey = info.dragNode.uuid;
            const dropPos = info.node.pos.split('-');
            const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
            const loop = (data, uuid, callback) => {
                for (let i = 0; i < data.length; i++) {
                    if (data[i].uuid === uuid) return callback(data[i], i, data)
                    if (data[i].children) loop(data[i].children, uuid, callback)
                }
            }
            const data = [...TreeData]
            let dragObj;
            loop(data, dragKey, (item, index, arr) => {
                arr.splice(index, 1)
                dragObj = item
            })
            if (!info.dropToGap) {
                loop(data, dropKey, item => {
                    item.children = item.children || []
                    item.children.unshift(dragObj);
                });
            } else {
                let ar = [], i
                loop(data, dropKey, (_item, index, arr) => { ar = arr; i = index })
                if (dropPosition === -1) ar.splice(i, 0, dragObj)
                else ar.splice(i + 1, 0, dragObj)
            }
            setTreeData(data);
        }

        return (
            <div className='SetTopOptions'>
                <Tree
                    className='TreeBox'
                    blockNode
                    draggable
                    defaultExpandAll
                    treeData={TreeData || []}
                    fieldNames={{ key: 'uuid' }}
                    selectedKeys={[]}
                    onDrop={onDrop}
                    titleRender={e => {
                        return (
                            <div className='TreeItem'>
                                <div>
                                    <div>
                                        {subset === 'top' && MappingData.System__AlignmentLHR.find(v => v.value === e.position).label + ' - '}
                                        {TypeMapping[subset].type.find(v => v.value === e.type)?.label}
                                    </div>
                                    <div style={{ color: e.color }}>{ICONMapping[e.icon]}{e.title}</div>
                                    <div>{e.tips}</div>
                                </div>
                                <div>
                                    {(e.type === 'A01' || e.type === 'A02' || e.type === 'B01' || e.type === 'B10') &&
                                        <Button type='link' onClick={() => onField(e)}>字段</Button>
                                    }
                                    {e.type === 'A03' && <Button type='link' onClick={() => onSearch(e)}>字段</Button>}
                                    {e.type === 'A04' && <Button type='link' onClick={() => onSort(e)}>字段</Button>}

                                    <Button type='link' onClick={() => onModify(e)}>修改</Button>
                                    {e.type === 'A01' && <Button type='link' onClick={() => onBands(e)}>列头</Button>}
                                    <Popconfirm
                                        title="删除提醒!"
                                        description="是否要删除当前操作?"
                                        onConfirm={() => onDelete(e.uuid)}
                                        okText="删除"
                                        cancelText="取消"
                                    >
                                        <Button type='link' danger >删除</Button>
                                    </Popconfirm>
                                </div>
                            </div>
                        )
                    }}
                />
                <div className='Save'>
                    <Button type='primary' onClick={onAddOptions}>新增操作</Button>
                    <Button type='primary' onClick={onSaveButton}>保存数据</Button>
                </div>
            </div>
        )
    }
};

export default SetAdminRouter